package com.cndw.kungfu.event;

import com.cndw.asyncsync.DataSyncServer;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.core.LogSyncServer;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.NumberProcesser;

/**
 * 智能优化调整
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2011-12-20 下午5:22:38
 */
public class IntelligenceOptimizeHandler extends BaseHandler implements Runnable {

	public static final int delaySeconds = 60;

	private static boolean openOpitimize = true;

	private int lastLogSize = 0;
	private int lastDataSize = 0;
	private static int sysDefaultGcLevel = 0;

	private static final int[] speedRange = { 800, 20000, 12000, 120000 };

	public IntelligenceOptimizeHandler() {
		sysDefaultGcLevel = ConstantsConfig.getSysCgGcLevel();
		if (ConstantsConfig.getSysAysncSpeedMinute() <= 100) {
			openOpitimize = false;
		}
		// log.info("IntelligenceOptimizeHandler");
	}

	@Override
	public void run() {
		// log.info("IntelligenceOptimizeHandler");
		try {
			if (!openOpitimize || ConstantsConfig.isSysClosed()) {
				return;
			}

			optimizeLog();
			optimizeData();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private boolean optimizeData() {
		int dataSzie = DataSyncServer.getInstance().size();
		int speed = DataSyncServer.getInstance().getMinuteSpeed();
		int step = DataSyncServer.getInstance().getPoolSize();
		int speedNew = speed;

		if (dataSzie < speed + 100) {
			speedNew = speed * 9 / 10 / 100 * 100;
		} else {
			int minuteNum = dataSzie + speed - lastDataSize;
			speedNew = minuteNum / 100 * 100;
		}
		lastDataSize = dataSzie;
		speedNew = NumberProcesser.between(speedNew, speedRange[0], speedRange[1]);
		if (Math.abs(speedNew - speed) < 200) {
			return false;
		} else if (speedNew <= ConstantsConfig.getSysAysncSpeedMinute()) {
			return false;
		}
		if (speedNew != speed) {
			DataSyncServer.getInstance().setSpeedAndStep(speedNew, step);
			LogUtil.getSystem().info("intelligence optimize DataSyncServer " + speedNew + "/" + step);
		}

		return true;
	}

	private boolean optimizeLog() {
		int dataSize = LogSyncServer.getInstance().size();
		int speed = LogSyncServer.getInstance().getSpeed();
		int step = LogSyncServer.getInstance().getStep();
		int speedNew = speed;

		if (dataSize < speed + 100) {
			speedNew = speed * 8 / 10 / 100 * 100;
		} else {
			int minuteNum = dataSize + speed - lastLogSize;
			speedNew = minuteNum / 100 * 100;
		}
		lastLogSize = dataSize;
		speedNew = NumberProcesser.between(speedNew, speedRange[2], speedRange[3]);
		if (Math.abs(speedNew - speed) < 200) {
			return false;
		} else if (speedNew <= speedRange[2]) {
			return false;
		}
		if (speedNew != speed) {
			if (speedNew >= 60000) {
				step = 200;
			} else if (step == 200) {
				step = 100;
			}
			LogSyncServer.getInstance().setSpeedAndStep(speedNew, step);
			LogUtil.getSystem().info("intelligence optimize LogSyncServer " + speedNew + "/" + step);
		}
		return true;
	}

	public static boolean test() {
		if (sysDefaultGcLevel != 0) {
			ConstantsConfig.setSysCgGcLevel(sysDefaultGcLevel);
		}
		return true;
	}

	public static void setOpenOpitimize(boolean openOpitimize) {
		IntelligenceOptimizeHandler.openOpitimize = openOpitimize;
	}

	public static boolean isOpenOpitimize() {
		return openOpitimize;
	}

}
